//! HTML解析器测试运行器
//!
//! 这个模块用于运行HTML解析器的测试用例

use html_parser::{DomNode, HtmlParser, HtmlValidator, NodeType, ParserConfig};

fn main() {
    println!("开始运行HTML解析器测试...");

    run_basic_html_test();
    run_selector_test();
    run_serialization_test();
    run_validation_test();
    run_dom_manipulation_test();

    println!("所有测试通过!");
}

fn run_basic_html_test() {
    println!("测试1: 基本HTML解析");

    let parser = HtmlParser::new(ParserConfig::default());
    let html = r#"
        <!DOCTYPE html>
        <html>
            <head>
                <title>测试页面</title>
            </head>
            <body>
                <h1>标题</h1>
                <p>这是一个段落</p>
            </body>
        </html>
    "#;

    let result = parser.parse(html);
    assert!(result.is_ok(), "HTML解析应该成功");
    println!("✓ 基本HTML解析测试通过");
}

fn run_selector_test() {
    println!("测试2: 选择器功能");

    let html = r#"
        <div class="container">
            <p id="first">第一段</p>
            <p class="highlight">第二段</p>
            <span data-test="value">测试span</span>
        </div>
    "#;

    let parser = HtmlParser::new(ParserConfig::default());
    let dom = parser.parse(html).unwrap();

    // 测试ID选择器
    let results = parser.query_selector(&dom, "#first").unwrap();
    assert_eq!(results.len(), 1);
    assert!(matches!(&results[0].node_type, NodeType::Element(tag) if tag == "p"));

    // 测试类选择器
    let results = parser.query_selector(&dom, ".highlight").unwrap();
    assert_eq!(results.len(), 1);
    assert!(matches!(&results[0].node_type, NodeType::Element(tag) if tag == "p"));

    // 测试属性选择器
    let results = parser.query_selector(&dom, "[data-test]").unwrap();
    assert_eq!(results.len(), 1);
    assert!(matches!(&results[0].node_type, NodeType::Element(tag) if tag == "span"));

    println!("✓ 选择器功能测试通过");
}

fn run_serialization_test() {
    println!("测试3: HTML序列化");

    let parser = HtmlParser::new(ParserConfig::default());
    let html =
        r#"<!DOCTYPE html><html><head><title>测试</title></head><body><p>内容</p></body></html>"#;

    let dom = parser.parse(html).expect("解析HTML应该成功");
    let serialized = parser.to_html(&dom, false);

    // 验证序列化结果包含所有必要的标签
    assert!(serialized.contains("<!DOCTYPE html>"));
    assert!(serialized.contains("<html>"));
    assert!(serialized.contains("<head>"));
    assert!(serialized.contains("<title>"));
    assert!(serialized.contains("<body>"));
    assert!(serialized.contains("<p>"));
    assert!(serialized.contains("测试"));
    assert!(serialized.contains("内容"));

    println!("✓ HTML序列化测试通过");
}

fn run_validation_test() {
    println!("测试4: HTML验证功能");

    let validator = HtmlValidator::new();
    let parser = HtmlParser::new(ParserConfig::default());

    // 测试无效嵌套
    let html = "<span><div>这是无效的嵌套</div></span>";
    let dom = parser.parse(html).expect("HTML解析应该成功");

    let result = validator.validate(&dom);
    assert!(result.is_err(), "应当检测到无效嵌套");

    // 测试无效子元素
    let html = "<ul><p>错误的子元素</p></ul>";
    let dom = parser.parse(html).expect("HTML解析应该成功");

    let result = validator.validate(&dom);
    assert!(result.is_err(), "应当检测到无效子元素");

    println!("✓ HTML验证功能测试通过");
}

fn run_dom_manipulation_test() {
    println!("测试5: DOM操作功能");

    // 创建DOM结构
    let mut root = DomNode::new_element("div");
    root.add_attribute("class", "container");

    let mut p1 = DomNode::new_element("p");
    p1.add_attribute("class", "intro highlight");
    p1.add_child(DomNode::new_text("这是第一段"));

    let mut p2 = DomNode::new_element("p");
    p2.add_attribute("class", "content");
    p2.add_child(DomNode::new_text("这是第二段"));

    root.add_child(p1);
    root.add_child(p2);

    // 测试has_class方法
    let p1 = &root.children[0];
    assert!(p1.has_class("intro"));
    assert!(p1.has_class("highlight"));
    assert!(!p1.has_class("content"));

    // 测试text_content方法
    assert_eq!(root.text_content(), "这是第一段这是第二段");
    assert_eq!(p1.text_content(), "这是第一段");

    println!("✓ DOM操作功能测试通过");
}
